#include "LZP.h"

LZP::LZP()
{
}

LZP::~LZP()
{
	cout << "destructor LZP"<< endl;
}

void LZP::comprimir(string nombreArch, BitHandlerOutput &pbho, int posi)
{
	BloqueTextoEntrada bt(nombreArch);
	manejadorDeArboles manejador;
	pbho.seek(posi);
	manejador.setBitHandlerOutput(pbho);
	bool archivoCerrado = false;

	int contador = 0;
	while(!bt.finArchivo())
	{
		unsigned char ctx1,ctx2;
		int pos=2;
		ctx1=bt[0];
		ctx2=bt[1];
		manejador.emitirCaracter((unsigned int)ctx1);
		manejador.emitirCaracter((unsigned int)ctx2);

		Indice indice;
		while(!bt.finBloque())
		{
			//contador++;
			//cout << contador<<endl;
			//cout << "pos carac actual: "<< pos <<endl;

			Compresion*cmp = new Compresion(pos);
			cmp->setContexto(ctx1, ctx2);
			cmp=indice.generarCompresion(cmp,bt);
			manejador.emitirLongitud(cmp->getLongitud());
			pos+=cmp->getLongitud();

			if(bt.finArchivo())
			{

				manejador.emitirEof();
				cout << "cerrar file comprimido 1" << endl;
				pbho.cerrarArchivo();//esta linea no estaba y por eso no se guardaban los cambios
				archivoCerrado = true;


			}

			else
			{
				manejador.emitirCaracter((unsigned char)bt[pos]);
				ctx1=bt[pos-1];
				ctx2=bt[pos];
				pos++;
			}
			//cout << "v"<<endl;

			delete cmp;

			//cout << "r"<<endl;

		}
		if(!bt.finArchivo())
		{
			cout << "d"<<endl;

			bt.llenarBloque();
			if(!archivoCerrado && bt.finArchivo()){//REVISAR
				//cout << "7"<<endl;

				manejador.emitirEof();
				cout << "cerrar file comprimido 2" << endl;
				pbho.cerrarArchivo();//esta linea no estaba y por eso no se guardaban los cambios
			}
		}
		//cout << "fin while grande" << endl;

	}
	cout << "	return 0" << endl;

	//return 0;//pbho.tell();
}

void LZP::descomprimir(string nombreArch, BitHandlerInput &pbhi, int posi){
	BloqueTextoSalida bts(nombreArch);
	manejadorDeArboles manejador;
	pbhi.resetEof();
	manejador.setBitHandlerInput(pbhi);
	pbhi.seek(posi);

	while(!bts.finArchivo())
	{
		char ctx1,ctx2;
		int pos=2;
		ctx1=manejador.obtenerCaracter();
		bts.setCaracterEnPos(ctx1,0);
		ctx2=manejador.obtenerCaracter();
		bts.setCaracterEnPos(ctx2,1);
		if(pbhi.eofVirtual())
		{
		 bts.setFinBloque(true);
		 bts.setFinArchivo(true);
		}
		Indice indice;

		while(!bts.finBloque())
		{
			int longi = manejador.obtenerLongitud();
			int carac = manejador.obtenerCaracter();

			if(pbhi.eofVirtual())
			{
				bts.setFinBloque(true);
				bts.setFinArchivo(true);
			}

			Compresion*cmp=new Compresion(pos);
			cmp->setLongitud(longi);
			cmp->setCaracter(carac);

			cmp->setContexto(ctx1,ctx2);
			cmp=indice.generarDescompresion(cmp,bts);



			pos+=longi;
			ctx1=bts[pos-1];
			ctx2=bts[pos];
			pos++;
			delete cmp;
		}

		if(pbhi.eofVirtual()) bts.setFinArchivo(true);
		if(!bts.finArchivo()){
			bts.vaciarBloque();
			cout << "!bts.finArchivo() " << endl;

		}
	}
	bts.vaciarBloque();
	bts.close();
}
